package org.meetunexpectedly.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.meetunexpectedly.entity.user.Favorites;
import org.meetunexpectedly.entity.user.FavoritesVideo;
import org.meetunexpectedly.entity.vo.FavoritesVO;
import org.meetunexpectedly.exception.BaseException;
import org.meetunexpectedly.holder.UserHolder;
import org.meetunexpectedly.mapper.user.FavoritesMapper;
import org.meetunexpectedly.service.user.FavoritesService;
import org.meetunexpectedly.service.user.FavoritesVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 收藏夹实现类
 * @Author: pupil
 * @Date: 2024/08/07 下午 9:30
 */
@Service
public class FavoritesServiceImpl extends ServiceImpl<FavoritesMapper, Favorites> implements FavoritesService {

    @Autowired
    private FavoritesVideoService favoritesVideoService;

    @Override
    public Boolean favoritesState(Long videoId, Long userId) {
        if (userId == null) return false;
        // 收藏数等于1为已收藏   收藏数等于0为未收藏
        return favoritesVideoService.count(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getVideoId, videoId).eq(FavoritesVideo::getUserId, userId)) == 1;
    }

    @Override
    public void exist(Long userId, Long favoritesId) {
        int count = this.count(new LambdaQueryWrapper<Favorites>().eq(Favorites::getId, favoritesId).eq(Favorites::getUserId, userId));
        if (count == 0) {
            throw new BaseException("收藏夹选择错误");
        }
    }

    @Override
    public List<Long> listVideoIds(Long favoriteId, Long userId) {
        Favorites favorites = this.getOne(new LambdaQueryWrapper<Favorites>().eq(Favorites::getId, favoriteId).eq(Favorites::getUserId, userId));
        if (ObjectUtils.isEmpty(favorites)) {
            throw new BaseException("该收藏夹不存在");
        }

        List<Long> videoIds = favoritesVideoService.list(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getFavoritesId, favoriteId).eq(FavoritesVideo::getUserId, userId))
                .stream().map(FavoritesVideo::getVideoId).collect(Collectors.toList());

        return videoIds;
    }

    @Override
    public Boolean favoritesVideo(Long favoritesId, Long videoId) {
        Long userId = UserHolder.get();
        Favorites favorites = this.getOne(new LambdaQueryWrapper<Favorites>().eq(Favorites::getId, favoritesId).eq(Favorites::getUserId, userId));
        if (favorites == null) {
            throw new BaseException("该收藏夹不存在");
        }

        try {
            FavoritesVideo favoritesVideo = new FavoritesVideo();
            favoritesVideo.setFavoritesId(favoritesId);
            favoritesVideo.setUserId(userId);
            favoritesVideo.setVideoId(videoId);
            favoritesVideoService.save(favoritesVideo);
        } catch (Exception e) {
            favoritesVideoService.remove(new LambdaQueryWrapper<FavoritesVideo>()
                    .eq(FavoritesVideo::getFavoritesId, favoritesId)
                    .eq(FavoritesVideo::getVideoId, videoId)
                    .eq(FavoritesVideo::getUserId, userId));
            return false;
        }
        return true;
    }

    @Override
    public Collection<Favorites> getUserFavorites(Long userId) {
        // 根据用户id获取所有收藏夹
        List<Favorites> favorites = this.list(new LambdaQueryWrapper<Favorites>().eq(Favorites::getUserId, userId));
        if (ObjectUtils.isEmpty(favorites)) {
            return Collections.emptyList();
        }
        // 根据收藏夹id获取对应的收藏数
        List<Long> fIds = favorites.stream().map(Favorites::getId).collect(Collectors.toList());
        Map<Long, Long> fMap = favoritesVideoService.list(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getFavoritesId, fIds))
                .stream().collect(Collectors.groupingBy(FavoritesVideo::getFavoritesId, Collectors.counting())); // 查询出数据集合进行分组统计元素数量

        for (Favorites favorite : favorites) {
            Long videoCount = fMap.get(favorite.getId());
            favorite.setVideoCount(videoCount == null ? 0 : videoCount);
        }

        return favorites;
    }

    @Override
    public Favorites getFavoritesById(Long id) {
        Favorites favorites = this.getById(id);
        if (ObjectUtils.isEmpty(favorites)) {
            throw new BaseException("指定收藏夹不存在");
        }

        int videoCount = favoritesVideoService.count(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getId, favorites.getId()));
        favorites.setVideoCount((long) videoCount);

        return favorites;
    }

    @Override
    public FavoritesVO saveOrUpdateFavorites(Favorites favorites) {
        // 创建结果集
        FavoritesVO favoritesVO = new FavoritesVO();

        favorites.setUserId(UserHolder.get());
        int count;
        if (favorites.getId() == null) {
            count = this.count(new LambdaQueryWrapper<Favorites>()
                    .eq(Favorites::getUserId, favorites.getUserId())
                    .eq(Favorites::getName, favorites.getName()));
        } else {
            count = this.count(new LambdaQueryWrapper<Favorites>()
                    .eq(Favorites::getUserId, favorites.getUserId())
                    .eq(Favorites::getName, favorites.getName())
                    .ne(Favorites::getId, favorites.getId()));
        }

        if (count == 1) {
            favoritesVO.setResult(false);
            favoritesVO.setMessage("已存在相同名称的收藏夹");
            return favoritesVO;
        }

        this.saveOrUpdate(favorites);
        favoritesVO.setResult(true);
        favoritesVO.setMessage(favorites.getId() != null ? "修改成功" : "添加成功");

        return favoritesVO;
    }

    @Override
    public Boolean deleteFavorites(Long id, Long userId) {
        Favorites favorites = this.getOne(new LambdaQueryWrapper<Favorites>().eq(Favorites::getId, id).eq(Favorites::getUserId, userId));
        if (ObjectUtils.isEmpty(favorites)) {
            throw new BaseException("指定收藏夹不存在");
        }
        if (favorites.getName().equals("默认收藏夹")) {
            throw new BaseException("默认收藏夹不允许被删除");
        }

        boolean result = this.remove(new LambdaQueryWrapper<Favorites>().eq(Favorites::getId, id).eq(Favorites::getUserId, userId));
        // 如果删除成功说明是自己的收藏夹
        if (result) {
            result = favoritesVideoService.remove(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getFavoritesId, id).eq(FavoritesVideo::getUserId, userId));
        }

        return result;
    }
}
